const _toString = Object.prototype.toString

export function isString(value) {
  const type = typeof value
  return type === 'string'
}

export function isNumber(value) {
  const type = typeof value
  return type === 'number'
}

export function isPrimitive(value) {
  const type = typeof value
  return type === 'number' || type === 'string'
}

export function isPlainObj(obj) {
  return _toString.call(obj) === '[object Object]'
}

export function isArray(obj) {
  return Array.isArray(obj)
}

export function isDef(value) {
  return value !== null && value !== undefined
}

export function deepCopy(obj, source) {
  if (isPlainObj(obj)) {
    if (!source) {
      source = {}
    }
    for (const key in obj) {
      const value = obj[key]
      if (isPlainObj(value)) {
        source[key] = deepCopy(value)
      } else if (Array.isArray(value)) {
        const arr = []
        for (let i = 0; i < value.length; i++) {
          const item = value[i]
          if (isPrimitive(item)) {
            arr.push(item)
          } else {
            arr.push(deepCopy(item))
          }
        }
        source[key] = arr
      } else {
        source[key] = value
      }
    }
  } else if (Array.isArray(obj)) {
    if (!source) {
      source = []
    }
    for (let i = 0; i < obj.length; i++) {
      const item = obj[i]
      if (isPrimitive(item)) {
        source.push(item)
      } else {
        source.push(deepCopy(item))
      }
    }
  }
  return source
}
